package com.zc.ex.userProvider.server.impl;

import com.zc.ex.userProvider.common.BaseResult;
import com.zc.ex.userProvider.common.InitData;
import com.zc.ex.userProvider.dto.UserInfoQueryDTO;
import com.zc.ex.userProvider.enums.OrderBy;
import com.zc.ex.userProvider.model.UserInfo;
import com.zc.ex.userProvider.server.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private static transient Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    private static Object obj = new Object();

    @Override
    public BaseResult<UserInfo> addUserInfo(UserInfo userInfo) {
        BaseResult<UserInfo> result = new BaseResult<>();
        try {
            synchronized (obj) {
                InitData.seq++;
                userInfo.setId(InitData.seq);
            }
            InitData.userInfos.add(userInfo);
            updateUserInfoIndex();
            result.successContent(userInfo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.failureContent(e.getMessage());
        }
        return result;
    }

    @Override
    public BaseResult<UserInfo> updateUserInfo(UserInfo userInfo) {
        BaseResult<UserInfo> result = new BaseResult<>();
        try {
            Long id = userInfo.getId();
            if (Objects.isNull(id)) {
                throw new Exception("无法获取用户信息");
            }
            InitData.userInfos.addIfAbsent(userInfo);
            updateUserInfoIndex();
            result.successContent(userInfo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.failureContent(e.getMessage());
        }
        return result;
    }

    @Override
    public BaseResult<List<UserInfo>> queryUserInfo(UserInfoQueryDTO queryDTO) {
        BaseResult<List<UserInfo>> result = new BaseResult<>();
        try {
            if (CollectionUtils.isEmpty(InitData.userInfos)) {
                result.successContent(new ArrayList<>());
            } else {
                List<UserInfo> content = new ArrayList<>();
                if (Objects.nonNull(queryDTO)) {
                    if (Objects.nonNull(queryDTO.getOrderBy())) {
                        OrderBy orderBy = queryDTO.getOrderBy();
                        switch (orderBy) {
                            case ID:
                                content = InitData.userInfos.stream().sorted(Comparator.comparing(UserInfo::getId))
                                        .collect(Collectors.toList());
                                break;
                            case LoginName:
                                content = InitData.userInfos.stream().sorted(Comparator.comparing(UserInfo::getLoginName))
                                        .collect(Collectors.toList());
                                break;
                            default:
                                content = InitData.userInfos.stream().sorted(Comparator.comparing(UserInfo::getId))
                                        .collect(Collectors.toList());
                        }
                    }
                    result.successContent(content);
                    return result;
                }
                content = InitData.userInfos.stream().sorted(Comparator.comparing(UserInfo::getId))
                        .collect(Collectors.toList());
                result.successContent(content);
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.failureContent(e.getMessage());
        }
        return result;
    }

    @Override
    public BaseResult<UserInfo> delUserInfo(Long id) {
        BaseResult<UserInfo> result = new BaseResult<>();
        try {
            if (Objects.isNull(id)) {
                throw new Exception("无法获取用户信息");
            }
            UserInfo userInfo = InitData.userInfoIndex.get(id);
            if (Objects.isNull(userInfo)) {
                logger.warn("没有对应的数据");
            }
            InitData.userInfos.remove(userInfo);
            updateUserInfoIndex();
            result.successContent(userInfo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.failureContent(e.getMessage());
        }
        return result;
    }

    private void updateUserInfoIndex() {
        synchronized (InitData.userInfos) {
            if (InitData.userInfoIndex.isEmpty() && CollectionUtils.isEmpty(InitData.userInfos)) {
                InitData.userInfoIndex = InitData.userInfos.stream().collect(Collectors.toMap(UserInfo::getId, item -> item));
            }
        }
    }
}
